home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 051-075 / 074 / less / main.c < prev    next >
C/C++ Source or Header  |  1995-03-13  |  7KB  |  393 lines

  1. /*
  2.  * Entry point, initialization, micellaneous routines.
  3.  */
  4.  
  5.  
  6. #include "less.h"
  7. #include "position.h"
  8. #include <setjmp.h>
  9.  
  10. public int      ispipe;
  11. public jmp_buf  main_loop;
  12. public char *   first_cmd;
  13. public char *   every_first_cmd;
  14. public int      new_file;
  15. public int      is_tty;
  16. public char     current_file[128];
  17. public int ac;
  18.  
  19. #ifdef amiga
  20. /* max items and chars that *.c can expand to */
  21. #define MAXTEMPLATES 100
  22. #define MAXARGVCHARS 1000
  23. public char    local_buffer[MAXARGVCHARS];
  24. public char    *local_av[MAXTEMPLATES];
  25. #endif
  26. public char **av;
  27. public int curr_ac;
  28. #if EDITOR
  29. public char *   editor;
  30. #endif
  31.  
  32. extern int file;
  33. extern int nbufs;
  34. extern int sigs;
  35. extern int quit_at_eof;
  36. extern int p_nbufs, f_nbufs;
  37. extern int back_scroll;
  38. extern int top_scroll;
  39. extern int sc_height;
  40.  
  41. /*
  42.  * Edit a new file.
  43.  * Filename "-" means standard input.
  44.  * No filename means the "current" file, from the command line.
  45.  */
  46.     public void
  47. edit(filename)
  48.     char *filename;
  49. {
  50.     register int f;
  51.     char message[100];
  52.     static int any_edited = 0;
  53.     static int hold_scroll = 0;
  54.  
  55.     if (filename == NULL || *filename == '\0')
  56.     {
  57.         if (curr_ac >= ac)
  58.         {
  59.             error("No current file");
  60.             return;
  61.         }
  62.         filename = av[curr_ac];
  63.     }
  64.  
  65.  
  66.     if (strcmp(filename, "-") == 0)
  67.         f = 0;  /* Standard input */
  68.     else if ((f = open(filename, 0)) < 0)
  69.     {
  70. #ifdef amiga
  71.         sprintf(message, "Cannot open %s", filename);
  72. #else
  73.         sprintf(message, "Cannot open %.*s", error_width()-13, filename);
  74. #endif
  75.         if (any_edited)
  76.             error(message);
  77.         else
  78.         {
  79.             puts(message);
  80. #ifdef amiga
  81.             flush();
  82.             /* wait two seconds for him to read message */
  83.             Delay(100L);
  84. #endif
  85.             hold_scroll = 1;
  86.         }
  87.         return;
  88.     }
  89.  
  90.     if (isatty(f))
  91.     {
  92.         /*
  93.          * Not really necessary to call this an error,
  94.          * but if the control terminal (for commands)
  95.          * and the input file (for data) are the same,
  96.          * we get weird results at best.
  97.          */
  98.         error("Can't take input from a terminal");
  99.         if (f > 0)
  100.             close(f);
  101.         return;
  102.     }
  103.  
  104.     /*
  105.      * Close the current input file and set up to use the new one.
  106.      */
  107.     if (file > 0)
  108.         close(file);
  109.     new_file = 1;
  110.     strcpy(current_file, filename);
  111. #ifndef amiga
  112.     ispipe = (f == 0);
  113. #endif
  114.     file = f;
  115.     ch_init( (ispipe) ? p_nbufs : f_nbufs );
  116.     init_mark();
  117.     if (every_first_cmd != NULL)
  118.         first_cmd = every_first_cmd;
  119.     if (is_tty)
  120.     {
  121.         any_edited = 1;
  122.         if (hold_scroll)
  123.         {
  124.             /*
  125.              * Before erasing the screen contents,
  126.              * display the file name and ask for a keystroke.
  127.              */
  128.             error(filename);
  129.             hold_scroll = 0;
  130.         }
  131.         if (first_cmd == NULL || *first_cmd == '\0')
  132.         {
  133.             /* 
  134.              * Display the first screen. 
  135.              */
  136.             jump_back(1);
  137.         } else
  138.         {
  139.             /* 
  140.              * The first_cmd will hopefully redisplay the
  141.              * screen, so we need not display anything yet.
  142.              * Indicate there is nothing yet on the screen. 
  143.              */
  144.             pos_clear();
  145.         }
  146.     }
  147. }
  148.  
  149. /*
  150.  * Edit the next file in the command line list.
  151.  */
  152.     public void
  153. next_file(n)
  154.     int n;
  155. {
  156.     if (curr_ac + n >= ac)
  157.     {
  158.         if (quit_at_eof)
  159.             quit();
  160.         error("No (N-th) next file");
  161.     } else
  162.         edit(av[curr_ac += n]);
  163. }
  164.  
  165. /*
  166.  * Edit the previous file in the command line list.
  167.  */
  168.     public void
  169. prev_file(n)
  170.     int n;
  171. {
  172.     if (curr_ac - n < 0)
  173.         error("No (N-th) previous file");
  174.     else
  175.         edit(av[curr_ac -= n]);
  176. }
  177.  
  178. /*
  179.  * Copy a file directly to standard output.
  180.  * Used if standard output is not a tty.
  181.  */
  182.     static void
  183. cat_file()
  184. {
  185.     register int c;
  186.  
  187.     while ((c = ch_forw_get()) != EOF)
  188.         putc(c);
  189.     flush();
  190. }
  191.  
  192. #ifdef amiga
  193.  
  194. /* Bob Leivian  4/28/87 fudge up things so it will work
  195.    when called from Work Bench */
  196. char argvbuf[80];
  197. int called_from_WB = 0;
  198. long old_dir;
  199.  
  200. #include "workbench/startup.h"
  201.  
  202. /* ignore AZTECs wb stuff */
  203. _wb_parse(ignore, ignore2)
  204. char *ignore;
  205. char *ignore2;
  206. {
  207.     return;
  208. #endif
  209.  
  210.  
  211. /*
  212.  * Entry point.
  213.  */
  214. main(argc, argv)
  215.     int argc;
  216.     char *argv[];
  217. {
  218.     char *getenv();
  219.     int i,j;
  220.  
  221. #ifdef amiga
  222. /* if we were called from the workbench we will have no args
  223.    but a pointer to the WB struct, get the filename from this structure */
  224. if(argc == 0) {
  225.    struct WBStartup *WBmsg;
  226.    struct WBArg *p;
  227.  
  228.    /* the argv is really the work bench structure */
  229.    WBmsg = (struct WBStartup *) argv;
  230.    p = WBmsg->sm_ArgList;
  231.  
  232.    p++;  /* ignore first parm */
  233.    strcpy(argvbuf, p->wa_Name);
  234.  
  235.    argc = 2;
  236.    argv[0] = "less";
  237.    argv[1] = argvbuf;        /* fake up the args now */
  238.  
  239.    /* we have to set up this icons current directory  (and release it later) */
  240.    called_from_WB++;
  241.    old_dir = CurrentDir(p->wa_Lock);
  242.  
  243. }
  244. #endif
  245.  
  246.     /*
  247.      * Process command line arguments and LESS environment arguments.
  248.      * Command line arguments override environment arguments.
  249.      */
  250.     init_option();
  251.     scan_option(getenv("LESS"));
  252.     argv++;
  253.     while ( (--argc > 0) && 
  254.       (argv[0][0] == '-' || argv[0][0] == '+') && 
  255.       argv[0][1] != '\0')
  256.         scan_option(*argv++);
  257.  
  258. #if EDITOR
  259.     editor = getenv("EDITOR");
  260.     if (editor == NULL || *editor == '\0')
  261.         editor = EDIT_PGM;
  262. #endif
  263.  
  264.     /*
  265.      * Set up list of files to be examined.
  266.      */
  267.     ac = argc;
  268.     av = argv;
  269. #ifdef amiga
  270.     /* CLI doesn't expand templates link U*ix so we need to do it
  271.            'by hand' */
  272.  
  273.     for (i=0, j=0; i<ac; i++) {
  274.        int temp = 0;
  275.        char *p;
  276.        char *scdir();
  277.  
  278.        if(index(av[i], '*') || index(av[i], '?')) {
  279.  
  280.           /* this is a template it needs to be expanded */
  281.               while( (p = scdir(av[i])) && (j < MAXTEMPLATES)) {
  282.          strcpy(&local_buffer[temp], p);
  283.          local_av[j++] = &local_buffer[temp];
  284.          temp += (strlen(&local_buffer[temp]) +1);
  285.          if(temp > MAXARGVCHARS) break;
  286.           }
  287.        } else
  288.           local_av[j++] = av[i];
  289.     }
  290.     av = local_av;
  291.     ac = j;
  292. #endif
  293.     curr_ac = 0;
  294.  
  295.     /*
  296.      * Set up terminal, etc.
  297.      */
  298.     is_tty = isatty(1);
  299. #ifdef amiga
  300.     if (!is_tty && !called_from_WB)
  301. #else
  302.     if (!is_tty)
  303. #endif
  304.     {
  305.         /*
  306.          * Output is not a tty.
  307.          * Just copy the input file(s) to output.
  308.          */
  309.         if (ac < 1)
  310.         {
  311.             edit("-");
  312.             cat_file();
  313.         } else
  314.         {
  315.             do
  316.             {
  317.                 edit((char *)NULL);
  318.                 if (file >= 0)
  319.                     cat_file();
  320.             } while (++curr_ac < ac);
  321.         }
  322.         exit(0);
  323.     }
  324.  
  325.     raw_mode(1);
  326.     get_term();
  327.     open_getc();
  328.     init();
  329.  
  330.     if (back_scroll < 0)
  331.     {
  332.         /* {{ KLUDGE }} */
  333.         back_scroll = sc_height-1;
  334.         if (top_scroll)
  335.             back_scroll--;
  336.     }
  337.  
  338.     if (setjmp(main_loop))
  339.         quit();
  340.     init_signals();
  341.  
  342.     /*
  343.      * Select the first file to examine.
  344.      */
  345.     if (ac < 1)
  346.         edit("-");      /* Standard input */
  347.     else 
  348.     {
  349.         /*
  350.          * Try all the files named as command arguments.
  351.          * We are simply looking for one which can be
  352.          * opened without error.
  353.          */
  354.         do
  355.         {
  356.             edit((char *)NULL);
  357.             if (file >= 0)
  358.                 /* We can open this file. */
  359.                 break;
  360.             putc('\n');  flush();
  361.         } while (++curr_ac < ac);
  362.     }
  363.  
  364.     if (file >= 0)
  365.         commands();
  366.     quit();
  367. }
  368.  
  369. /*
  370.  * Exit the program.
  371.  */
  372.     public void
  373. quit()
  374. {
  375.     /*
  376.      * Put cursor at bottom left corner, clear the line,
  377.      * reset the terminal modes, and exit.
  378.      */
  379.     lower_left();
  380.     clear_eol();
  381.     deinit();
  382.     flush();
  383.     raw_mode(0);
  384. #ifdef amiga
  385.     ttclose();
  386.  
  387.     if(called_from_WB)
  388.         CurrentDir(old_dir);
  389. #endif
  390.     exit(0);
  391. }
  392.